/**
 * 
 */
package com.baijia.tianxiao.connect.interceptor;

import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;

import com.alibaba.dubbo.common.json.JSON;
import com.baijia.tianxiao.connect.config.Constants;
import com.baijia.tianxiao.connect.config.RegisterAddrConfig;
import com.baijia.tianxiao.connect.model.TxCCAuthToken;
import com.baijia.tianxiao.connect.route.api.enums.DeviceDomainEnum;
import com.baijia.tianxiao.connect.route.api.util.TxCcSessionKeyUtil;
import com.baijia.tianxiao.connect.util.TianxiaoConnectUtil;
import com.baijia.tianxiao.util.encrypt.EncryptUtils;;

/**
 * @author leiruiqi
 *
 */
public class TianxiaoAppWebSocketHandshakeInterceptor extends HttpSessionHandshakeInterceptor{

	
	private static Logger logger = LoggerFactory.getLogger(TianxiaoAppWebSocketHandshakeInterceptor.class);
	
	@Resource
	private TianxiaoConnectUtil tianxiaoConnectUtil;
	@Autowired
	private RegisterAddrConfig registerAddrConfig;
	
	private boolean initPort = false;
	
	public void afterHandshake(ServerHttpRequest arg0, ServerHttpResponse arg1, WebSocketHandler arg2, Exception arg3) {
		// TODO Auto-generated method stub
		
	}

	public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
			Map<String, Object> attributes) throws Exception {
		if (request instanceof ServletServerHttpRequest) {  
            ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
            //获取服务端口号，由于servlet api 中没有提供端口号特性，只有从request中获取，这里获取容器启动后的第一次request中的端口号
            if(!initPort){
            	int port = servletRequest.getServletRequest().getLocalPort();
            	tianxiaoConnectUtil.setLocalPort(port);
            	registerAddrConfig.registerAddr(TianxiaoConnectUtil.getRealIp(), port);
            	initPort = true;
            }
            
            String userToken = (String)servletRequest.getServletRequest().getParameter("user_token");
            
            
            TxCCAuthToken paramObject = checkTokenAndGetParams(userToken);
        	if(paramObject == null){
        		return false;
        	}
        	Integer tokenTime = paramObject.getCt();
            String bizType = paramObject.getBiz_type();
        	String userId = paramObject.getUser_id();
        	Integer deviceDomainCode = paramObject.getDevice_domain();
        	String deviceType = paramObject.getDeviceType();
        	String deviceId = paramObject.getDeviceId();
        	
        	//使用userName区分WebSocketHandler，以便定向发送消息  
            //String userName = (String) session.getAttribute(Constants.SESSION_USERNAME);  
			if (!StringUtils.isEmpty(bizType)  && !StringUtils.isEmpty(userId) && checkDeviceDomain(deviceDomainCode)&& checkExpire(tokenTime) ) {
				
				if(StringUtils.isBlank(deviceType)){
					deviceType = "0";
				}
				
				if(StringUtils.isBlank(deviceId)){
					deviceId = String.valueOf(System.currentTimeMillis());
				}
				String websocket_username = TxCcSessionKeyUtil.createTxSessionKey(bizType, userId, String.valueOf(deviceDomainCode),deviceType,deviceId);
				if (StringUtils.isBlank(websocket_username)) {
					response.setStatusCode(HttpStatus.FORBIDDEN);
					return false;
				}

				attributes.put(Constants.SESSION_USERNAME, websocket_username);
				attributes.put(Constants.USER_ID, userId);
				attributes.put(Constants.BIZ_TYPE, bizType);
				attributes.put(Constants.DEVICE_TYPE, deviceType);
				attributes.put(Constants.DEVICE_ID, deviceId);

				return true;
			}
        }  
		
	    response.setStatusCode(HttpStatus.FORBIDDEN);
		return false;
		
	}
	
	private TxCCAuthToken checkTokenAndGetParams(String userToken){
		TxCCAuthToken auth = null;
		try {
			String jsonString = EncryptUtils.strDecode(userToken);
		
			auth = JSON.parse(jsonString, TxCCAuthToken.class);
		} catch (Exception e) {
			logger.error("checkToken error",e);
			return null;
		}
		
		return auth;
	}
	
	private boolean checkDeviceDomain(Integer deviceDoomainCode){
		
		String codeStr = String.valueOf(deviceDoomainCode);
		
		DeviceDomainEnum deviceDomainEnum = DeviceDomainEnum.getByCode(codeStr);
		
		return deviceDomainEnum != null;
	}
	
	private boolean checkExpire(Integer tokenTime){
		if(tokenTime != null){
			long time = System.currentTimeMillis()/1000-tokenTime.longValue();
			//10分钟过期
			long expire = 600;
			//测试用过期时间
			long testExpire = 6;
			if(time>expire){
				return false;
			}
		}
		
		return true;
	}

	
}
